/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/
#include "MaCI_Logger_woWX.hpp"
#include <curses.h>
#include <stdio.h>
#include <iostream>

MaCI_Logger_woWX::MaCI_Logger_woWX(gimi::GIMI *g, 
                                    MaCI::MaCICtrl::CMaCICtrlClient *mcc)
  :iGimi(g),
   iMcc(mcc),
   iServices(),
   iUniqueServices(),
   iLoggerGenerator(),
   iSelectedServices(),
   iServiceMap(),
   iLoggers(),
   iLogging(false)
{
  iLoggerGenerator = new LoggerGenerator(g);

}
  
MaCI_Logger_woWX::~MaCI_Logger_woWX()
{
  StopLogging();
  DestroyLoggers();
  delete iLoggerGenerator;
}

void MaCI_Logger_woWX::Start(){
  DoMenu();

}


bool MaCI_Logger_woWX::DoSLScan()
{  
  using namespace MaCI::MaCICtrl;
  dPrint(1,"Running service Discovery");
  gimi::t_serviceList servicelist;
  iMcc->DiscoverMaCICtrlServices(servicelist);
  dPrint(1,"Got %u MaCICtrl compliant services", servicelist.size());
      
  dPrint(1,"Requesting information of ALL services using the ServiceList handling function.");
  std::string lastsl;

  if (iMcc->GetServiceArray(iServices, servicelist) == MaCI::KMaCIOK) {
    //    dPrint(1,"Got %d Entries of information, printing unique entries:", services.size());
    for(EACH_IN_i(iServices)){
      const std::string currentsl = i->GetMaCISL().ToMaCISLString();
      if(lastsl != currentsl){
        bool unique = true;
        for(unsigned int j = 0; j < iUniqueServices.size(); j++){
          if(iUniqueServices[j].GetMaCISL().ToMaCISLString() == currentsl){
            unique = false;
            break;
          }
        }
        if(unique){
          iSelectedServices[currentsl] = false;
          iServiceMap[currentsl] = *i;
          iUniqueServices.push_back(*i);
          lastsl = currentsl;
        }
      }
    }
    return true;
   
  } else {

    dPrint(1,"Failed to query information for Entries!");
    return false;   
        
  }
  return false;
}


void MaCI_Logger_woWX::PrintMaCIServices(){
 printw("\nSERVICES:\n");
  std::string lastsl;
  int index = 1;
  for(EACH_IN_i(iUniqueServices)) {
    const std::string currentsl = i->GetMaCISL().ToMaCISLString();
    
    if(iSelectedServices[currentsl]){
      printw("  S  ");
    }
    printw("%d. '%s'\n", 
           index,
           currentsl.c_str());
    index++;
    

  }

}

void MaCI_Logger_woWX::PrintMenu(){

  if(iLogging){
    printw("****************************************************\n");
    printw("**********************LOGGING***********************\n");   
    printw("****************************************************\n");   

  }
  PrintMaCIServices();

  printw("\nSelect CoordinateDrive Query:\n");
  if(!iLogging){
    printw("'u' = Update service list (Cancels the selection)\n");
    printw("'s' = Select services to log\n");
  
    printw("'1' = Start Logging\n");
  }if(iLogging){
    printw("'2' = Stop Logging\n");
  }
  printw("\n'q' = QUIT\n");
  printw("?\n");

}

void MaCI_Logger_woWX::DoMenu(){

 // Initialize Curses (After this point, don't use printf family calls!)
  initscr(); 
  cbreak(); 
  //noecho();
  nonl();
  intrflush(stdscr, FALSE);
  keypad(stdscr, TRUE);
  scrollok(stdscr, TRUE);
  //nodelay(stdscr, TRUE);
  //halfdelay(10);

  // After this point, we don't want dPrint to print to Screen, so we disable it.
  debugSetPrintLevel(0);
  debugSetLogLevel(5);
  
  clear();

  printw("Welcome to MaCI_Logger. Scanning GIMnet\n\n");

  /**
   * DO update in the beginning
   */
 
  DoSLScan();


  clear();
  
  bool run = true;
  do {
    clear();
    int value;
    PrintMenu();
    value = getch();
    clear();
   
    switch(value){
    case 'u':{
      if(!iLogging){
        DoSLScan();
      }
        
      break;
    }
    case 's':{
      if(!iLogging){
        SelectServices();
      }

      break;
    }
    case 'q':{
      printw("Bye bye");
      run = false;
      break;
    }

    case '1':{
      if(!iLogging){
        StartLogging();
      }
      break;
    }
    case '2':{
      if(iLogging){
        StopLogging();
      }
      break;
    }
    default :{
      clear();
      printw("\nUnknown command.\n\n");
      continue;
      break;
    }






    }
  }while(run);

  // Close curses.
  endwin();
}



void MaCI_Logger_woWX::SelectServices(){
  
  DestroyLoggers();


  bool run = true;
  while(run){
    clear();
    PrintMaCIServices();
    printw("\nSelect Services with index number and enter(0 to stop) :\n");
      
    int r;
    int value;
    r = scanw("%d",&value);
    printw("r = %d\n",r);
    printw("r = %d, value %d\n", r,value);
    // dPrint(1,"Unique services sie %d",iUniqueServices.size());
    if(r == 1 && value > 0 && value <=(int)iUniqueServices.size()){

      std::string macisl = iUniqueServices[value-1].GetMaCISL().ToMaCISLString();
      if(iSelectedServices[macisl]){
        iSelectedServices[macisl] = false;
      }else{
        iSelectedServices[macisl] = true;
      }      
      
    }else if(value == 0){
      run = false;

    }
    //    dPrint(1,"selected services %d",iSelectedServices.size());
  }

  ///Generate loggers
  //  dPrint(1,"selected services %d",iSelectedServices.size());


  for(EACH_IN_i(iSelectedServices)){
    if(iSelectedServices[i->first] == true){
      MaCI::MaCICtrl::SServiceEntry entry = iServiceMap[i->first];
      Logger *log =  iLoggerGenerator->GenerateNewLogger(entry.service.servicemajor,entry.service.serviceminor,
                                                         entry.gimnetid,entry.GetMaCISL().ToMaCISLString());
      
      iLoggers.push_back(log);
    }
    
    
  }


  
  

}

void MaCI_Logger_woWX::StartLogging(){
  dPrint(1,"Start logging.. n. of loggers %d", iLoggers.size());
  for(unsigned int i = 0 ; i< iLoggers.size(); i++){

    iLoggers[i]->StartLogging();

  }
  iLogging = true;

}
void MaCI_Logger_woWX::StopLogging(){

  dPrint(1,"Stop logging.. n. of loggers %d", iLoggers.size());
  if(iLogging){
    for(unsigned int i = 0 ; i< iLoggers.size(); i++){
      
      iLoggers[i]->StopLogging();
      
    }
  }
  iLogging = false;
}

void MaCI_Logger_woWX::DestroyLoggers(){
  /** for(unsigned int i = 0 ; i< iLoggers.size(); i++){
    delete iLoggers[i];

    }*/

  iLoggers.clear();

}
